﻿// //  ********************************************************************************
// //  Copyright (C) 2016 Sebastian Kenter. All rights reserved.
// // 
// //  Name    : MultiServerEngine | ServerFramework | ServerRequestForwardHandler.cs
// //  Created : 2016 - 02 - 16 20:53
// //  Modified: 2016 - 02 - 20 12:33
// //  ********************************************************************************

using System.Linq;
using ExitGames.Logging;
using ServerFramework.Implementation.Server;
using ServerFramework.Implementation.Telegram;
using ServerFramework.Interfaces.Server;
using ServerFramework.Interfaces.Telegram;
using TypeDefs;

namespace ServerFramework.Implementation.Handler.Forward
{
    public class ServerRequestForwardHandler : ServerTelegramHandler
    {
        private IServerPeerRegistry<IServerPeer> ServerPeerRegistry { get; }

        public override TelegramHandlerTypes HandlerType => TelegramHandlerTypes.Request;
        public override byte Code => (byte) OperationCodes.ForwardRequest;
        public override int? SubCode => null;

        public ServerRequestForwardHandler(ILogger logger, IServerPeerRegistry<IServerPeer> serverPeerRegistry)
            : base(logger)
        {
            ServerPeerRegistry = serverPeerRegistry;
        }

        public override bool HandleTelegram(ITelegram telegram, IServerPeer serverPeer)
        {
            Logger.InfoFormat("Handling forwarding request from peer id={0}", serverPeer.PeerId);

            ServerPeer peer =
                ServerPeerRegistry.GetServerPeers()
                    .Values.First(
                        c =>
                            c.GetHandledOperations()[HandlerTypes.ServerHandler].Contains((OperationCodes) telegram.Code))
                    as ServerPeer;

            if (peer != null)
            {
                Logger.InfoFormat("Found responsible server....forwarding");
                peer.SendTelegram(telegram);
            }

            Logger.ErrorFormat("No responsible server found. Sending back error response.");

            ServerPeer sPeer = serverPeer as ServerPeer;

            sPeer?.SendTelegram(new ResponseTelegram(telegram.Code, telegram.SubCode, telegram.Parameters,
                (short) ErrorCodes.InvalidOperation, "No server found."));

            return true;
        }
    }
}
